package com.mwj.generator.config;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.setting.dialect.Props;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.BeetlTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import lombok.Getter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.Arrays;

/**
 * @author mengweijin
 */
@Slf4j
@Getter
@ToString
public class ConfigProperty {

    private static final String CONFIG_PATH = "config.properties";

    private static final ConfigProperty INSTANCE = new ConfigProperty();

    private ConfigProperty() {
        Props props = new Props(CONFIG_PATH, CharsetUtil.UTF_8);
        author = props.getStr("author");
        outputPath = props.getStr("output.path");
        if(StrUtil.isBlank(outputPath) || !FileUtil.isDirectory(outputPath)) {
            log.warn("The output.path is not a valid output directory, the default directory will be used!");
            outputPath = System.getProperty("user.dir") + File.separator + "code";
        }
        templateEngineType = props.getStr("template.engine.type", TemplateEngineEnum.BEETL.name()).toUpperCase();
        packageParent = props.getStr("package.parent");
        moduleName = props.getStr("module.name", "").toLowerCase();
        tables = trimAndDistinct(props.getStr("tables").split(StringPool.COMMA));
        tablePrefix = props.getStr("table.prefix", moduleName + StringPool.UNDERSCORE);
        superEntityClass = props.getStr("super.entity.class");
        superEntityColumns = trimAndDistinct(props.getStr("super.entity.columns").split(StringPool.COMMA));
        dbUrl = props.getStr("db.url");
        dbDriverName = props.getStr("db.driverName");
        dbUsername = props.getStr("db.username");
        dbPassword = props.getStr("db.password");

        initTemplateEngine();

        log.debug(this.toString());
    }

    private void initTemplateEngine() {
        TemplateEngineEnum templateEngineEnum = EnumUtil.fromStringQuietly(TemplateEngineEnum.class, templateEngineType);
        switch (templateEngineEnum) {
            case VELOCITY:
                templateEngine = new VelocityTemplateEngine();
                templateSuffix = ".vm";
                break;
            case FREEMARKER:
                templateEngine = new FreemarkerTemplateEngine();
                templateSuffix = ".ftl";
                break;
            case BEETL:
                templateEngine = new BeetlTemplateEngine();
                templateSuffix = ".btl";
                break;
            default:
                break;
        }
    }

    public static ConfigProperty getInstance() {
        return INSTANCE;
    }

    private String author;

    private String outputPath;

    private String templateEngineType;

    private String packageParent;

    private String moduleName;

    private String[] tables;

    private String tablePrefix;

    private String superEntityClass;

    private String[] superEntityColumns;

    private String dbUrl;

    private String dbDriverName;

    private String dbUsername;

    private String dbPassword;

    private AbstractTemplateEngine templateEngine;

    private String templateSuffix;

    private String[] trimAndDistinct(String[] array) {
        return Arrays.stream(array).map(String::trim).distinct().toArray(String[]::new);
    }

}
